package com.bbu.javaexam.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 银行账户类
 * 演示100个线程同时向一个银行账户存入1元钱
 * 未使用同步机制
 */
public class Account {
    // 账户余额
    private double balance;

    private Lock lock = new ReentrantLock();

    /**
     * 存款
     *
     * @param money : 存入金额
     */
    public void deposit(double money) {
        lock.lock();
        try {
            double newBalance = balance + money;
            try {
                Thread.sleep(10);   // 模拟此业务需要一段处理时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            balance = newBalance;
        } finally {
            lock.unlock();
        }


    }

    /**
     * 获得账户余额
     *
     * @return : 账户余额
     */
    public double getBalance() {
        return balance;
    }


    public static void main(String[] args) {
        // 方式一
        Account account = new Account();
        // 方式二
//        Account02 account = new Account02();

        ExecutorService service1 = Executors.newFixedThreadPool(20);

        // 创建线程池
        ExecutorService service = Executors.newFixedThreadPool(100);
        for (int i = 1; i <= 100; i++) {
            /**
             * execute()：方法接收一个Runnable实例，并且异步执行
             */
//            service.execute(new AddMoneyThread(account,1));
            service.execute(() -> {
                synchronized (account) {
                    account.deposit(1);
                }
            });
        }
        /**
         * 当线程池调用该方法时，线程池的状态则立刻变成shutdown状态。此时，则不能在往线程池中添加任何任务，否则将会抛出异常。
         * 但是，此时线程池不会立刻退出，直到添加到线程池中的任务都已经处理完成，才会退出。
         */
        service.shutdown();
        /**
         * isTerminated（）：当调用shutdown()方法后，并且当所有提交的任务完成后返回true;
         */
        while (!service.isTerminated()) {
        }
        System.out.println("账户余额： " + account.getBalance());
    }

}
